package hotspot;

import java.io.IOException;
import java.util.Hashtable;
import java.util.LinkedList;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.border.TitledBorder;

import Vis.Users;
import Vis.Visualiser;
import bodyPosition.Position;
import bodyPosition.PositionStorage;

import comms.Communicator;
import comms.PhoneServer;

public class HotspotApp {

    //Hotspot
	protected LinkedList<Hotspot> hotspots = new LinkedList<Hotspot>();
//	public Hashtable<Integer,PositionStorage> bodyPositions;
	public Users users;
	protected Hotspot onHotspot = null;
	private PhoneServer server;
	//private JFrame hotspotFrame;
	private SpotMap spotMap;
	//protected double[] currentPos = null;
	
	protected double xRange=120, zRange=200;
	
	public HotspotApp(PhoneServer s, Users b, Visualiser v){
		server = s;
		users = b;             
		
		//hotspotFrame = new JFrame();
		spotMap = new SpotMap(this);
		spotMap.validate();		
		v.addMap(spotMap.container);
		
		//hotspotFrame.add(spotMap);
		
		//position the window
		//Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
		//hotspotFrame.setLocation(0, screensize.height - spotMap.height);
		
		//hotspotFrame.pack();
		//hotspotFrame.validate();
		//hotspotFrame.setVisible(true);
	}
	
	public synchronized void doHotspot(String place, Integer i) throws IOException{
		//currentPos = pos.clone();
		
		PositionStorage p = users.getUser(i).getPositionStorage();
		double[] pos = p.getBodyPosition(place).getPosition();

		
		Hotspot h=null;
//		double hMin = Double.MAX_VALUE;
		double xMin = Double.MAX_VALUE;
	 //  double zMin = Double.MAX_VALUE;
		synchronized(hotspots){
			//find hotspot
			for (Hotspot spot: hotspots){
				//if(spot.compare(pos))
					//h = spot;
				/*double newMin = spot.compareMin(pos); 
				if(Math.abs(newMin) < Math.abs(hMin)){
					h=spot;
					hMin = Math.abs(newMin);
				}*/
				double difX = spot.compareX(pos);
		//		double difZ = spot.compareZ(pos);
				if(Math.abs(difX) < Math.abs(xMin)
			 //  		&& Math.abs(difZ) < Math.abs(zMin)
          ){
					h=spot;
					xMin = Math.abs(difX);
					//zMin = Math.abs(difZ);
				}
			}
		}
//		double minRange = 80;  
		//Communicator.s.append("[HOTSPOT min " +  h.getId() + "] " + hMin);
		/*if(hMin > minRange)
			h = null;*/
		if(xMin > xRange)
      //|| zMin > zRange)
			h = null;
		
		//handle result

		if(h != null
      //&& onHotspot==null
      // TODO(norrielm) compare id of h and id of hotspot (if not null) to minimise checking here)
      ){
				onHotspot = h;
				Communicator.s.appendToAll("[HOTSPOT " +  h.getId() + "] " + h.getText());
				if(server==null)
					Communicator.s.appendToAll("Server null");
				try{
				server.sendToAll("Hotspot on " + h.getId() + " " +h.getText());
				}catch(Exception e){
					Communicator.s.appendToAll(e.getMessage());
				}
		}else if(h==null && onHotspot!=null){
			synchronized(onHotspot){
				server.sendToAll("Hotspot off");
				onHotspot = null;
			}
		}

		spotMap.repaint();
		
	}
	
	public void addHotspot(String text, Integer i){
		//get position data of user i
		if(i==null)
			return;
		PositionStorage bodyPos = users.getUser(i).getPositionStorage();;	
		Position position = bodyPos.getFirstBodyPosition();
		if(position==null)
			return;
		
		double[] pos = position.getPosition();
		long currentTime = System.currentTimeMillis();
		
		Hotspot h = new Hotspot(hotspots.size()+1, text, pos);
		synchronized(hotspots){
			hotspots.add(h);
		}
		System.out.println("[Client] Adding hotspot: " + h );
		if(server!=null)
			server.log.write(currentTime + " " + h.pos[0] + " "+ h.pos[1]+ " " + h.pos[2]);		  
		
		if((int)(position.getPosition()[2]/1000) > spotMap.MAX_Z){
			spotMap.MAX_Z = (int)(position.getPosition()[2]/1000 + spotMap.getZRange()*2);
		}
		
		spotMap.repaint();
	}
	
	public synchronized void addHotspot(String text){
		//no user specified: use first in table
		Integer i = null;
		if(!users.isEmpty()){
			i = users.getUserIDs().iterator().next();

			System.out.println("Add: User "+i);
		}
		addHotspot(text, i);		
	}
	
	
	
	public void clearHotspots(){
		synchronized(hotspots){
			hotspots.clear();
		}
	}
}
